//
//  SSDKHttpUtil.m
//  SuperSDK
//
//  Created by wyht－ios－dev on 15/10/6.
//  Copyright © 2015年 WYHT. All rights reserved.
//

#import "OpenSDK_HttpUtil.h"

#import "OpenSDK_DataKeys.h"

#import "OpenSDK_JsonUtil.h"

#import "OpenSDK_Enum.h"

#import "OpenSDK_DataManager.h"

#import "OpenSDK_EncryptUtil.h"
#import "OpenSDK_ReqDataGenerator.h"
#import "LocalizationManager.h"
#import "OpenSDK_Reachability.h"
#import "LocalizationManager.h"
#import "OpenSDK_UIManager.h"

@implementation OpenSDK_HttpUtil

static int const TIME_OUT = 8;

static OpenSDK_HttpUtil *instance = nil;

+(instancetype) getInstance {
    if (instance==nil) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[self alloc] init];
        });
    }
    return instance;
}

+ (void) postWithUrl : (NSString *)url
                data : (NSString *)data
        httpDelegate : (void (^)(OpenSDK_BaseResData* resData))gotInfo {
    
    //检查网络情况
    if (![OpenSDK_HttpUtil isNetworkReachable]) {
        OpenSDK_BaseResData *resData = [[OpenSDK_BaseResData alloc] init];
        [resData fail];
        [resData setErrorMsg:[LocalizationManager getValueByKey:OpenSDK_LOCALIZATION_NETWORKERROR]];
        [resData setErrorNo:OpenSDK_NETWORK_TIME_OUT];
        gotInfo(resData);
        return;
    }
    
    NSData *postData = [data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
    
    NSURL *nsUrl = [[NSURL alloc] initWithString:url];
    
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:TIME_OUT];
    request.HTTPMethod = @"POST";
    
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    
    [request setValue:[LocalizationManager getHttpLanHeaderValue] forHTTPHeaderField:@"Accept-Language"];
    //处理超时连接
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    
    request.HTTPBody = postData;
    
    [self dealWithRequest:request httpDelegate:gotInfo];
}

+ (void) postWithUrl : (NSString *)url
                data : (NSString *)data
              timeout: (NSUInteger)time
        httpDelegate : (void (^)(OpenSDK_BaseResData* resData))gotInfo {
    
    //检查网络情况
    if (![OpenSDK_HttpUtil isNetworkReachable]) {
        OpenSDK_BaseResData *resData = [[OpenSDK_BaseResData alloc] init];
        [resData fail];
        [resData setErrorMsg:[LocalizationManager getValueByKey:OpenSDK_LOCALIZATION_NETWORKERROR]];
        [resData setErrorNo:OpenSDK_NETWORK_TIME_OUT];
        gotInfo(resData);
        return;
    }
    
    NSData *postData = [data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
    
    NSURL *nsUrl = [[NSURL alloc] initWithString:url];
    
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:time];
    request.HTTPMethod = @"POST";
    
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    
    [request setValue:[LocalizationManager getHttpLanHeaderValue] forHTTPHeaderField:@"Accept-Language"];
    //处理超时连接
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    
    request.HTTPBody = postData;
    
    [self dealWithRequest:request httpDelegate:gotInfo];
}

+(void) getWithUrl:(NSString *)url data:(NSString *)data httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    //检查网络情况
    if (![OpenSDK_HttpUtil isNetworkReachable]) {
        OpenSDK_BaseResData *resData = [[OpenSDK_BaseResData alloc] init];
        [resData fail];
        [resData setErrorMsg:[LocalizationManager getValueByKey:OpenSDK_LOCALIZATION_NETWORKERROR]];
        [resData setErrorNo:OpenSDK_NETWORK_TIME_OUT];
        gotInfo(resData);
        return;
    }
    
    NSString *URLFellowString = (data!=nil?[@"?"stringByAppendingString:data]:@"");
    
    NSURL *nsUrl = [[NSURL alloc] initWithString:[url stringByAppendingString:URLFellowString]];
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:TIME_OUT];
    request.HTTPMethod = @"GET";
    [request setValue:[LocalizationManager getHttpLanHeaderValue] forHTTPHeaderField:@"Accept-Language"];
    //处理超时连接
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    
    [self dealWithRequest:request httpDelegate:gotInfo];
}

//delete方法
+(void) delWithUrl:(NSString *)url data:(NSString *)data httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    //检查网络情况
    if (![OpenSDK_HttpUtil isNetworkReachable]) {
        OpenSDK_BaseResData *resData = [[OpenSDK_BaseResData alloc] init];
        [resData fail];
        [resData setErrorMsg:[LocalizationManager getValueByKey:OpenSDK_LOCALIZATION_NETWORKERROR]];
        [resData setErrorNo:OpenSDK_NETWORK_TIME_OUT];
        gotInfo(resData);
        return;
    }
    
    NSString *URLFellowString = [@"?"stringByAppendingString:data];
    
    NSURL *nsUrl = [[NSURL alloc] initWithString:[url stringByAppendingString:URLFellowString]];
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:TIME_OUT];
    
    request.HTTPMethod = @"DELETE";
    
    [request setValue:[LocalizationManager getHttpLanHeaderValue] forHTTPHeaderField:@"Accept-Language"];
    //处理超时连接
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    [request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
    
    [self dealWithRequest:request httpDelegate:gotInfo];
}

+(void) dealWithRequest:(NSMutableURLRequest *)request
          httpDelegate : (void (^)(OpenSDK_BaseResData* resData))gotInfo {
    
    NSOperationQueue *queue = [NSOperationQueue new];
    
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *jsonData, NSError *error) {
        
        OpenSDK_BaseResData *resData = [[OpenSDK_BaseResData alloc] init];
        
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
        NSInteger status = [httpResponse statusCode];
        
        if (200 == status) {
            @try {
                NSString *dataStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                NSMutableDictionary *resDic = [OpenSDK_JsonUtil toObjectWithJson:dataStr];
                NSLog(@"response success \n data = %@",resDic);
                resData = [[OpenSDK_BaseResData alloc] initWithDictionary:resDic];
            }
            @catch (NSException *exception) {
                NSLog(@"response faiure %@",exception);
                [resData fail];
                [resData setErrorMsg:[LocalizationManager getValueByKey:OpenSDK_LOCALIZATION_SERVERERROR1]];
                [resData setErrorNo:OpenSDK_SERVER_RESPONSE_FORMAT_ILLEGAL];
            }
            // 在非ui线程回调
            if(gotInfo != nil) {
                gotInfo(resData);
            }
        } else {
            [resData fail];
            [resData setErrorMsg:[LocalizationManager getValueByKey:OpenSDK_LOCALIZATION_SERVERERROR2]];
            [resData setErrorNo:OpenSDK_NETWORK_TIME_OUT];
            // 在非ui线程回调
            gotInfo(resData);
        }
    }];
}

+(NSString *) urlEncode:(NSString *) urlStr {
    NSString *encodedValue = (NSString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(nil,
                                                                                                  (CFStringRef)urlStr, nil,
                                                                                                  (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8));
    if (encodedValue) {
        return encodedValue;
    }
    return @"";
}

+(void) initWithDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getInitUrl];
    NSString *data=[NSString stringWithFormat:@"grant_app=%@",[[OpenSDK_DataManager getInstance] appID]];
    [self getWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) quickLogin:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateQuickLoginData];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) loginWithTmpId:(NSString *)tmpId
          httpDelegate:(void (^)(OpenSDK_BaseResData* resData)) gotInfo {
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateTmpLoginData:tmpId];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) queryAppActiveStatus:(NSString *)affect
               httpDelegate : (void (^)(OpenSDK_BaseResData* resData)) gotInfo {
    NSString *url=[OpenSDK_DataManager getQueryActiveStatusUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateQueryActiveCodeData:affect];
    
    [self getWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) bindActiveCode:(NSString *)code
         httpDelegate : (void (^)(OpenSDK_BaseResData* resData)) gotInfo {
    NSString *url=[OpenSDK_DataManager getBindActiveCodeUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateBindActiveCodeData:code];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) findPasswordWithEmail:(NSString *) email
                 httpDelegate:(void (^)(OpenSDK_BaseResData* resData)) gotInfo {
    NSString *url=[OpenSDK_DataManager getFindPasswordUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateFindPasswordData:email];
    [self getWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) resetPasswordWithPhoneNumber:(NSString *)phoneNumber passwd:(NSString *)passwd randomPassword:(NSString *)randomPassword httpDelegate:(void (^)(OpenSDK_BaseResData* resData)) gotInfo {
    NSString *url=[OpenSDK_DataManager getResetPasswordUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateResetPasswordDataWithPhone:phoneNumber password:passwd randomPassword:randomPassword];
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) findPasswordWithPhone:(NSString *) phoneNumber
                 httpDelegate:(void (^)(OpenSDK_BaseResData* resData)) gotInfo {
    NSString *url=[OpenSDK_DataManager getFindPasswordUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateFindPasswordDataWithPhoneNumber:phoneNumber];
    [self getWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) registerWithPhoneNumber:(NSString *)phoneNumber passwd:(NSString *)passwd randomPassword:(NSString *)randomPassword httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getRegisterUrl];
    
    NSString *data=[OpenSDK_ReqDataGenerator generateRegistrationDataWithPhone:phoneNumber password:passwd randomPassword:randomPassword];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) registerWithUserName:(NSString *)userName passwd:(NSString *)passwd httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getRegisterUrl];
    
    NSString *data=[OpenSDK_ReqDataGenerator generateRegistrationDataWithName:userName password:passwd];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) loginWithPhoneNumber:(NSString *)phoneNumber randomPasswd:(NSString *)randomPasswd 
                httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateUserCheckDataWithPhoneNumber:phoneNumber randomPassword:randomPasswd];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) sendSMSWithPhoneNumber:(NSString *)phoneNumber smsType:(NSString *)smsType httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getSMSUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateSMSDataWithPhoneNumber:phoneNumber smsType:smsType];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) loginWithPhoneNumber:(NSString *)phoneNumber passwd:(NSString *)passwd httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateUserCheckDataWithPhoneNumber:phoneNumber password:passwd];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

// 一键登录
+(void) loginWithOneKeyToken:(NSString *)token httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateUserCheckDataWithLoginToken:token];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) loginWithUserName:(NSString *)userName passwd:(NSString *)passwd httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateUserCheckDataWithName:userName password:passwd];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) bindingWithPhoneNumber:(NSString *)phoneNumber
                        passwd:(NSString *)passwd
                randomPassword:(NSString *)randomPassword
                        openId:(NSString *)openId
                         token:(NSString *)token
                      platform:(NSString *)platform
                  httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getUserBindingUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateBindingDataPhoneNumber:phoneNumber password:passwd randomPassword:randomPassword openId:openId token:token platform:platform];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) bindingWithUserName:(NSString *)userName passwd:(NSString *)passwd httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getUserBindingUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateBindingDataWithName:userName password:passwd];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) bindingWithOtherSDK:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getUserBindingUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateBindingDataWithOtherSDK];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) logoutWithToken:(NSString *)token UID:(NSString *)UID httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateLogoutDataWithToken:token uid:UID];
    
//    [self dealWithRequest:url data:data httpDelegate:gotInfo];
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

//第三方SDK登录
+(void) loginWithOtherSDK:(NSDictionary *)params platform:(NSString *)platform platformVersion:(NSString *)platformVersion httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSMutableDictionary *data = [OpenSDK_ReqDataGenerator generateInitDataWithInfo];
    if (params != nil) {
        [data addEntriesFromDictionary:params];
    }
    [data setObject:platform forKey:OpenSDK_S_OAUTH_TYPE];
    [data setObject:platformVersion forKey:OpenSDK_S_PLATFORM_VERSION];
    NSLog(@"kkk: %@", data.description);
    NSString *dataStr = [OpenSDK_ReqDataGenerator generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
    [self postWithUrl:url data:dataStr httpDelegate:gotInfo];
}

+(void) checkUserWithToken:(NSString *)token openID:(NSString *)openID httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getUserCheckUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateUserCheckDataWithToken:token openID:openID];
    [self getWithUrl:url data:data httpDelegate:gotInfo];
}

+(void) getGameProtrolWithDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getProtrolUrl];
    [self getWithUrl:url data:nil httpDelegate:gotInfo];
}

+(void) createOrderWithPayInfo:(id)payInfo httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    NSString *url=[OpenSDK_DataManager getPayUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateCreateOrderDataWithPayInfo:payInfo];
    
    [self postWithUrl:url data:data httpDelegate:^(OpenSDK_BaseResData *resData) {
        if (resData.errorNo == 1013){
            dispatch_async(dispatch_get_main_queue(), ^{
                [[OpenSDK_UIManager getInstance] loginInvalid];
            });
        }
        gotInfo(resData);
    }];
}

+(void) checkOrderWithOrderInfo:(NSString *)orderInfo
                        orderID:(NSString *)orderID
                   httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo
{
    //为了适配苹果补单的情况，需要处理orderID为空的情况
    NSString *url;
    if(orderID==nil || orderID.length==0) {
        url=[OpenSDK_DataManager getOrderCheckUrl];
    } else {
        url=[[OpenSDK_DataManager getPayUrl] stringByAppendingString:[@"/" stringByAppendingString:orderID]];
    }
    [self postWithUrl:url data:orderInfo httpDelegate:^(OpenSDK_BaseResData *resData) {
        if (resData.errorNo == 1013){
            dispatch_async(dispatch_get_main_queue(), ^{
                [[OpenSDK_UIManager getInstance] loginInvalid];
            });
        }
        gotInfo(resData);
    }];
}

+ (void)checkAppleOrderWithParams:(NSString *)params httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url = [OpenSDK_DataManager getAppleOrderCheckUrl];
    [self postWithUrl:url data:params timeout:180 httpDelegate:^(OpenSDK_BaseResData *resData) {
        if (resData.errorNo == 1013){
            dispatch_async(dispatch_get_main_queue(), ^{
                [[OpenSDK_UIManager getInstance] loginInvalid];
            });
        }
        gotInfo(resData);
    }];
}

+ (void)checkApplePromoOrderWithParams:(NSString *)params httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url = [OpenSDK_DataManager getApplePromoOrderCheckUrl];
    [self postWithUrl:url data:params timeout:180 httpDelegate:gotInfo];
}

+(BOOL) isNetworkReachable
{
    BOOL isReachable = NO;
    OpenSDK_Reachability *reachability = [OpenSDK_Reachability reachabilityWithHostName:@"opensdk.sail2world.com"];
    switch ([reachability currentReachabilityStatus]) {
        case NotReachable:{
            isReachable = NO;
        }
            break;
            //        case ReachableViaWWAN:{
            //            isReachable = YES;
            //        }
            //            break;
            //        case ReachableViaWiFi:{
            //            isReachable = YES;
            //        }
            //            break;
        default:
            isReachable = YES;
            break;
    }
    return isReachable;
}

//检查用户是否实名制
+(void) checkRealNameWithOpenID:(NSString *)openID
                          token:(NSString *)token
                   httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getUserRealNameUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateCheckRealNameDataWithOpenID:openID token:token];
    [self getWithUrl:url data:data httpDelegate:gotInfo];
}

//进行实名认证
+(void) realNameWithOpenID:(NSString *)openID
                     token:(NSString *)token
                  realName:(NSString *)name
                cardNumber:(NSString *)cardNumber
               phoneNumber:(NSString *)phoneNumber
                  security:(NSString *)security
              httpDelegate:(void (^)(OpenSDK_BaseResData *))gotInfo {
    NSString *url=[OpenSDK_DataManager getUserRealNameUrl];
    NSString *data=[OpenSDK_ReqDataGenerator generateRealNameDataWithOpenID:openID token:token realName:name cardNumber:cardNumber phoneNumber:phoneNumber security:security];
    
    [self postWithUrl:url data:data httpDelegate:gotInfo];
}

//获取商品id列表
+(void) getProductIds:(void (^)(OpenSDK_BaseResData* resData)) gotInfo {
    NSString *url = [OpenSDK_DataManager getProductUrl];
    NSMutableDictionary *data = [OpenSDK_ReqDataGenerator generateInitDataWithInfo];
    
    NSString *dataStr = [OpenSDK_ReqDataGenerator generateDataByDictionary:data];
    return [OpenSDK_HttpUtil getWithUrl:url data:dataStr httpDelegate:gotInfo];
}

@end
